#include "ae_device.h"

using namespace RFIDLIB;

CAEDevice::CAEDevice(QObject *parent) : QObject(parent)
{

}
CAEDevice::~CAEDevice()
{

}
DWORD CAEDevice::get_antenna_count()
{
    return RDR_GetAntennaInterfaceCount(hRdr);// disable async tag report output
}

//获取设备信息
int CAEDevice::GetReaderInfor(char * pinfo,int &len)
{
    DWORD nSize=128;
    CHAR temp[128]={'\0'};
    if(hRdr==NULL)
    {
        return -ERR_CLOSED;
    }
    int iret = RDR_GetReaderInfor(hRdr,0,temp,&nSize);
    if(iret != NO_ERR)
        return iret;

    if(len<nSize)
        return -ERR_MEMSIZE;

    memset(pinfo,'\0',len);
    memcpy(pinfo,temp,nSize);
    len=nSize;
    return iret;
}

//获取空中协议类型
BYTE CAEDevice::get_air_type(const char *m_RDType)
{
    BYTE air_type=0;
    if(strcmp(m_RDType,"RL8000")==0)
    {
        air_type |= (AIR_ISO15693|AIR_ISO14443A);
    }
    else if(strcmp(m_RDType,"UM200")==0)
    {
        air_type |= AIR_ISO180006C;
    }
    else {
        air_type |= AIR_ISO15693;
    }
    return air_type;
}

void * CAEDevice::Inventory_Loop(void * hr)
{
    CAEDevice *pr=(CAEDevice*)hr;

    err_t iret;

    DWORD tagCount ;

    ULONGLONG tick=GetTickCount();
    int loop_count=0;

    if(pr->RDType_ID==0)
        pr->m_tags_hf.clear();
    else
        pr->m_tags_uhf.clear();

    while(pr->loop)//wait any key to exit
    {
        usleep(1*1000);
        tick=GetTickCount();

        if(pr->RDType_ID==0)
            pr->m_tags_hf.clear();
        else
            pr->m_tags_uhf.clear();

        iret = pr->func_Inventory();
        if(iret == NO_ERR)
        {
            loop_count++;
            if(pr->RDType_ID==0)
            {
                tagCount =pr->m_tags_hf.size();
                emit pr->sgnl_inventory_data_hf(tagCount,pr->m_tags_hf,GetTickCount()-tick,loop_count);
            }
            else
            {
                tagCount =pr->m_tags_uhf.size();
                emit pr->sgnl_inventory_data_uhf(tagCount,pr->m_tags_uhf,GetTickCount()-tick,loop_count);
            }
        }
        else
            break;
    }

    if(pr->hRdr != NULL)
        RDR_ResetCommuImmeTimeout(pr->hRdr);//reset timout status
    pr->loop=false;
    pr->is_inventory=false;
    emit pr->sgnl_inventory_end_loop(iret);
    return 0;
}

err_t CAEDevice::Open(LPTSTR connStr)
{
    if(hRdr != NULL)
        return NO_ERR;
    if(m_opened)
        return NO_ERR;

    int iret = RDR_Open(connStr,&hRdr);
    if(iret != NO_ERR)
    {
        return iret;
    }
    m_opened=true;
    return iret;
}

err_t CAEDevice::Close()
{
    if(hRdr==NULL)
        return NO_ERR;
    if(!m_opened)
        return NO_ERR;
    if(is_inventory)
    {
        stop_inventory();
        while(!is_inventory)
            usleep(10000);
    }

    int iret = RDR_Close(hRdr);
    m_opened=false;
    hRdr=NULL;
    return iret;
}

err_t CAEDevice::start_inventory(const char *m_RDType, BYTE antennas[], BYTE ant_cnt)
{
    if(this->loop && this->is_inventory)
        return NO_ERR;
    this->air_type=this->get_air_type(m_RDType);

    memset(this->antennas,0,this->ant_count);
    memcpy(this->antennas,antennas,ant_cnt);
    this->ant_count=ant_cnt;

    int iret;
    pthread_t pThrd;
    this->loop=true;
    this->is_inventory=true;
    iret= pthread_create(&pThrd,NULL,Inventory_Loop,this);
    if(iret != 0)
    {
        this->loop=false;
        this->is_inventory=false;
        printf("create run Inventory_Loop thread failed! ret=%d",iret);
    }
    return iret;

}

void CAEDevice::stop_inventory()
{
    if(this->hRdr==NULL)
        return;
    if(!this->is_inventory || !this->loop)
        return;
    RDR_SetCommuImmeTimeout(this->hRdr);
    this->loop=false;
}


err_t CAEDevice::func_Inventory()
{
    return -ERR_NOCMD;
}


//HF Write Blocks
err_t CAEDevice::func_AccessTag_WriteData(CTag &tag,DWORD block_addr,DWORD block_num,BYTE* data,DWORD dlen)
{
    return -ERR_NOCMD;
}

//UHF Write Blocks
err_t CAEDevice::func_AccessTag_WriteData(CTag &tag,DWORD accessPwd,BYTE mem_type, DWORD mem_addr_word, DWORD mem_num_word, BYTE *data, DWORD dlen)
{
    return -ERR_NOCMD;
}

//HF Read Blocks
err_t CAEDevice::func_AccessTag_ReadData(CTag &tag,DWORD block_addr,DWORD block_num,BYTE* data,DWORD *dlen)
{
    return -ERR_NOCMD;
}

//UHF Read Blocks
err_t CAEDevice::func_AccessTag_ReadData(CTag &tag,DWORD accessPwd,BYTE mem_type, DWORD mem_addr_word, DWORD mem_num_word, BYTE *data, DWORD &dlen)
{
    return -ERR_NOCMD;
}


//Enable/Disable ESA
err_t CAEDevice::func_AccessTag_EnDisable_EAS(CTag &tag,bool bEnable)
{
    return -ERR_NOCMD;
}
//Check ESA
err_t CAEDevice::func_AccessTag_Check_EAS(CTag &tag,BYTE &eas_sta)
{
    return -ERR_NOCMD;
}

//Read or Write AFI
//bRead: true=Read AFI,else Write AFI
err_t CAEDevice::func_AccessTag_Write_AFI(CTag &tag,BYTE afi)
{
    return -ERR_NOCMD;
}

//Get tag's information about:
//SDFID AFI BLOCK_SIZE BLOCK_NUMBERS
err_t CAEDevice::func_AccessTag_GetInfor(CTag &tag,BYTE *dsfid, BYTE *afi,DWORD *block_size,DWORD *block_num, BYTE *ic_ref)
{
    return -ERR_NOCMD;
}


err_t CAEDevice::func_AccessTag_UHF_Kill_Tag(CTag &tag, DWORD accessPwd, DWORD killPwd, BYTE rfu)
{
    return -ERR_NOCMD;
}


//LSG Control Center
void * CAEDevice::GetRecords_Loop(void * hr)
{
    CAEDevice *pr=(CAEDevice*)hr;

    err_t iret;

    DWORD tagCount ;

    ULONGLONG tick=GetTickCount();
    int loop_count=0;

    if(pr->RDType_ID==0)
        pr->m_tags_hf.clear();
    else
        pr->m_tags_uhf.clear();

    DWORD total_in=0;
    DWORD total_out=0;
    DWORD day_in=0;
    DWORD day_out=0;

    if(pr->hRdr != NULL)
        RDR_ResetCommuImmeTimeout(pr->hRdr);//reset timout status
    bool deleteFlag=false;
    while(pr->loop)//wait any key to exit
    {
        usleep(1*1000);
        tick=GetTickCount();

        pr->m_rcd_alarm.clear();
        pr->m_rcd_day.clear();
        pr->m_rcd_realtime.clear();

        iret = pr->func_LSGCC_GetRecords(&deleteFlag,pr->Get_Record_Addtionflag,pr->Get_Record_Gate_id,&total_in,&total_out,&day_in,&day_out);
        if(iret == NO_ERR)
        {
            loop_count++;
            emit pr->sgnl_lsgcc_get_records(pr->m_rcd_alarm,pr->m_rcd_day,pr->m_rcd_realtime,total_in,total_out,day_in,day_out,GetTickCount()-tick,loop_count);
        }
        else
            break;
    }

    if(pr->hRdr != NULL)
        RDR_ResetCommuImmeTimeout(pr->hRdr);//reset timout status
    pr->loop=false;
    pr->is_inventory=false;
    emit pr->sgnl_lsgcc_get_records_end_loop(iret);
    return 0;
}

int CAEDevice::start_get_records(DWORD Addtionflag, BYTE gate_id)
{
    if(this->loop && this->is_get_records)
        return NO_ERR;
    this->Get_Record_Addtionflag = Addtionflag;
    this->Get_Record_Gate_id = gate_id;

    int iret;
    pthread_t pThrd;
    this->loop=true;
    this->is_get_records=true;
    iret= pthread_create(&pThrd,NULL,GetRecords_Loop,this);
    if(iret != 0)
    {
        this->loop=false;
        this->is_get_records = false;
        printf("create run func_LSGCC_GetRecords thread failed! ret=%d",iret);
    }
    return iret;
}
void CAEDevice:: stop_get_records()
{
    if(this->hRdr==NULL)
        return;
    if(!this->is_get_records || !this->loop)
        return;
    RDR_SetCommuImmeTimeout(this->hRdr);
    this->loop=false;
}

err_t CAEDevice::func_LSGCC_SinglelDoor_Alarm(BYTE gate_id){
    return -ERR_NOCMD;
}
err_t CAEDevice::func_LSGCC_SinglelDoor_SetOutput(BYTE gate_id,BYTE output_ids[],BYTE output_len,BYTE type,BYTE freq,DWORD at,DWORD dt){
    return -ERR_NOCMD;
}
err_t CAEDevice::func_LSGCC_SinglelDoor_SetAtmosphereLight(BYTE gate_id,BYTE light_id,BYTE type,BYTE freq,DWORD at,DWORD dt){
    return -ERR_NOCMD;
}
err_t CAEDevice::func_LSGCC_SinglelDoor_GetIRTriggerCount(BYTE gate_id,DWORD ir_ids[],BYTE* ir_nums){
    return -ERR_NOCMD;
}
err_t CAEDevice::func_LSGCC_InitPC(BYTE type,DWORD inPC,DWORD outPC){
    return -ERR_NOCMD;
}
err_t CAEDevice::func_LSGCC_GetPC(BYTE option, DWORD * pcInTotal, DWORD * pcOutTotal, DWORD * pcInDay, DWORD * pcOutDay){
    return -ERR_NOCMD;
}
err_t CAEDevice::func_LSGCC_GetSystemTime(DWORD* year,BYTE* month,BYTE* day,BYTE* hour,BYTE* minute,BYTE* second){
    return -ERR_NOCMD;
}
err_t CAEDevice::func_LSGCC_SetSystemTime(DWORD year,BYTE month,BYTE day,BYTE hour,BYTE minute,BYTE second){
    return -ERR_NOCMD;
}
err_t CAEDevice::func_LSGCC_GetRecords(bool* deleteFlag,DWORD Addtionflag,BYTE gate_id,DWORD* total_in,DWORD* total_out,DWORD* day_in,DWORD* day_out){
    return -ERR_NOCMD;
}

//Scan/Buffer Mode
err_t CAEDevice::func_Scan_Mode_Fetch_Tags(DWORD scan_mode_flag)
{
    int iret = RDR_BuffMode_FetchRecords(hRdr,scan_mode_flag);
    if(iret != NO_ERR)
        return iret;
    RFID_DN_HANDLE dnhReport = RDR_GetTagDataReport(hRdr,RFID_SEEK_FIRST);
    while (dnhReport != NULL) {

        BYTE bytsData[256];
        DWORD blen=sizeof(bytsData);
        char sData[blen*2];
        memset(sData,'\0',blen);

        iret = RDR_ParseTagDataReportRaw(dnhReport,bytsData,&blen);
        if(iret != NO_ERR)
            break;
        if(blen > 0)
        {
            CScan_Record rcd;
            BytesToHexStr(bytsData,blen,sData);
            rcd.m_data = QString(sData);
            rcd.m_counter = 1;
            m_scan_records.push_back(rcd);
        }

        dnhReport = RDR_GetTagDataReport(hRdr,RFID_SEEK_NEXT);
    }

}
void * CAEDevice::Scan_Mode_Loop(void * hr)
{
    CAEDevice *pr=(CAEDevice*)hr;

    err_t iret;

    DWORD tagCount ;

    ULONGLONG tick=GetTickCount();
    int loop_count=0;

    pr->m_scan_records.clear();
    iret = RDR_BuffMode_ClearRecords(pr->hRdr);//
    if(iret != NO_ERR)
        goto exit_flag;

    pr->scan_mode_flag = 0x00;
    while(pr->loop)//wait any key to exit
    {
        usleep(1*1000);
        tick=GetTickCount();

        pr->m_scan_records.clear();

        iret = pr->func_Scan_Mode_Fetch_Tags(pr->scan_mode_flag);
        if(iret == NO_ERR)
        {
            pr->scan_mode_flag = 0x01;//采集后更新标识
            loop_count++;
            tagCount =pr->m_scan_records.size();
            emit pr->sgnl_scan_mode_data(tagCount,pr->m_scan_records,GetTickCount()-tick,loop_count);
        }
        else
            break;
    }

exit_flag:
    if(pr->hRdr != NULL)
        RDR_ResetCommuImmeTimeout(pr->hRdr);//reset timout status
    pr->loop=false;
    pr->is_scan_mode=false;
    emit pr->sgnl_scan_mode_end_loop(iret);
    return 0;
}

err_t CAEDevice::start_scan_mode(const char *m_RDType)
{
    if(this->loop && this->is_scan_mode)
        return NO_ERR;

    int iret;
    pthread_t pThrd;
    this->loop = true;
    this->is_scan_mode = true;
    iret= pthread_create(&pThrd,NULL,Scan_Mode_Loop,this);
    if(iret != 0)
    {
        this->loop=false;
        this->is_scan_mode = false;
        printf("create run Scan_Mode_Loop thread failed! ret=%d",iret);
    }
    return iret;

}

void CAEDevice::stop_scan_mode()
{
    if(this->hRdr==NULL)
        return;
    if(!this->is_scan_mode || !this->loop)
        return;
    RDR_SetCommuImmeTimeout(this->hRdr);
    this->loop=false;
}


